#pragma once // 确保头文件只被编译一次，避免重复定义错误

#include <iostream>     // 标准输入输出流，尽管这里没有直接使用，但通常是C++文件的标配
#include <string>       // 字符串类，用于处理IP地址字符串
#include <sys/types.h>  // 包含基本系统数据类型，如 `__socket_type`
#include <sys/socket.h> // 包含套接字相关的函数和结构，如 `sockaddr_in`
#include <arpa/inet.h>  // 包含 `inet_ntoa` 和字节序转换函数（如 `ntohs`）
#include <netinet/in.h> // 包含 `in_addr_t` 和 `sockaddr_in` 等网络地址结构

// InetAddr 类：封装网络地址信息（IP地址和端口号）
// 提供了方便的方法来访问和转换这些信息。
class InetAddr
{
private:
    // _addr 是私有成员变量，存储底层的 sockaddr_in 结构体
    // 这个结构体包含了IP地址和端口号，是网络编程中表示地址的标准方式
    struct sockaddr_in _addr;
    // _ip 是私有成员变量，存储点分十进制的IP地址字符串
    std::string _ip;
    // _port 是私有成员变量，存储主机字节序的端口号
    uint16_t _port;

private:
    // GetAddress 方法：从内部存储的 sockaddr_in 结构中提取IP地址和端口号
    // ip 参数是一个指向 std::string 的指针，用于存储提取出的IP地址
    // port 参数是一个指向 uint16_t 的指针，用于存储提取出的端口号
    void GetAddress(std::string *ip, uint16_t *port)
    {
        // ntohs(): network to host short
        // 将网络字节序的端口号（_addr.sin_port）转换为主机字节序，并赋值给 *port
        *port = ntohs(_addr.sin_port);
        // inet_ntoa(): converts network address to dotted-decimal string
        // 将网络字节序的IP地址（_addr.sin_addr）转换成点分十进制字符串，并赋值给 *ip
        // 注意：inet_ntoa 返回一个静态 char* 缓冲区，因此需要立即复制到 std::string
        *ip = inet_ntoa(_addr.sin_addr);
    }

public:
    // 构造函数：接受一个 const sockaddr_in 引用作为参数
    // addr 参数是被封装的网络地址结构体
    InetAddr(const struct sockaddr_in &addr) : _addr(addr)
    {
        // 在构造时调用 GetAddress 方法，从传入的 sockaddr_in 中解析出IP和端口
        GetAddress(&_ip, &_port);
    }

    // Ip 方法：获取封装的IP地址字符串
    std::string Ip()
    {
        return _ip; // 返回存储的IP地址字符串
    }

    // 重载 == 运算符：用于比较两个 InetAddr 对象是否相等
    // addr 参数是要比较的另一个 InetAddr 对象的引用
    bool operator==(const InetAddr &addr)
    {
        // if(_ip == addr._ip) // 原有注释，此处未做改动
        // 比较两个 InetAddr 对象的IP地址和端口号是否都相同
        // 只有IP和端口都相同才认为地址相同，这对于测试非常方便和精确。
        if (_ip == addr._ip && _port == addr._port) // 方便测试
        {
            return true; // 地址相同
        }
        return false; // 地址不同
    }

    // Addr 方法：获取底层的 sockaddr_in 结构体
    // 返回其内部存储的 sockaddr_in 结构体的副本
    struct sockaddr_in Addr()
    {
        return _addr;
    }

    // Port 方法：获取封装的端口号（主机字节序）
    uint16_t Port()
    {
        return _port; // 返回存储的端口号
    }

    // 析构函数：释放资源（这里没有动态分配的资源，所以为空）
    ~InetAddr()
    {
    }

}; // class InetAddr